package com.example.ivos.application.service.impl;

import com.example.ivos.application.mapper.ApplicationMapper;
import com.example.ivos.application.pojo.dto.ApplicationParam;
import com.example.ivos.application.pojo.dto.ApplicationQuery;
import com.example.ivos.application.pojo.entity.Application;
import com.example.ivos.application.pojo.vo.ApplicationVO;
import com.example.ivos.application.service.ApplicationService;
import com.example.ivos.audit.pojo.dto.AuditQuery;
import com.example.ivos.audit.pojo.entity.Audit;
import com.example.ivos.audit.pojo.vo.AuditVO;
import com.example.ivos.audit.service.AuditService;
import com.example.ivos.base.enums.ApplicationStatusEnum;
import com.example.ivos.user.mapper.UserMapper;
import com.example.ivos.user.pojo.dto.UserQuery;
import com.example.ivos.user.pojo.vo.UserVO;
import com.example.ivos.vehicle.mapper.VehicleMapper;
import com.example.ivos.vehicle.pojo.entity.Vehicle;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.StringJoiner;
import java.util.stream.Collectors;

@Transactional
@Service
@Slf4j
public class ApplicationServiceImpl implements ApplicationService {
    @Autowired
    private ApplicationMapper applicationMapper;

    @Autowired
    private AuditService auditService;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private VehicleMapper vehicleMapper;

    @Override
    public void save(ApplicationParam applicationParam) {
        log.debug("申请单业务applicationParam:{}", applicationParam);
        Application application = new Application();
        BeanUtils.copyProperties(applicationParam, application);
        application.setStatus(ApplicationStatusEnum.PENDING.getCode());
        application.setCreateTime(new Date());
        /*遇到的问题：新增申请单时，无法给对应的审批单数据传入申请单id*/
        //原因：id是一个比较特殊的属性，无法直接通过某一个条件select获取
        /*解决方案：给insert方法对应的sql语句上加：
         * useGeneratedKeys="true" keyProperty="id"*/
        //效果：JDBC会为当前application对象自动生成自增主键，并且把生成的主键值
        //赋值给当前application对象的id属性
        applicationMapper.insert(application);
        //还需要为此申请单生成对应的审批单数据
        auditService.insertAudit(application);
    }

    @Override
    public void cancel(ApplicationParam applicationParam) {
        log.debug("撤销申请单业务applicationParam:{}", applicationParam);
        Application application = new Application();
        BeanUtils.copyProperties(applicationParam, application);
        application.setStatus(ApplicationStatusEnum.CANCELLED.getCode());
        application.setUpdateTime(new Date());
        applicationMapper.update(application);
        Long id = application.getId();
        auditService.removeAudit(id);
    }

    @Override
    public void update(ApplicationParam applicationParam) {
        log.debug("更新申请单业务applicationParam:{}", applicationParam);
        Application application=new Application();
        BeanUtils.copyProperties(applicationParam, application);
        application.setUpdateTime(new Date());
        if(application.getStatus().equals(ApplicationStatusEnum.ALLOCATION.getCode())){
            log.debug("申请单状态为：{}，分配用车",application.getStatus());
            Vehicle vehicle = new Vehicle();
            vehicle.setId(application.getVehicleId());
            vehicle.setStatus("2");
            vehicleMapper.update(vehicle);
            applicationMapper.update(application);
        }else{
            log.debug("申请单状态为：{}，归还用车",application.getStatus());
            Vehicle vehicle = new Vehicle();
            ApplicationQuery applicationQuery =new ApplicationQuery();
            applicationQuery.setId(application.getId());
            List<ApplicationVO> select = applicationMapper.select(applicationQuery);
            vehicle.setId(select.get(0).getVehicleId());
            vehicle.setStatus("1");
            vehicleMapper.update(vehicle);
            applicationMapper.update(application);
        }
    }

    @Override
    public List<ApplicationVO> select(ApplicationQuery applicationQuery) {
        log.debug("查询申请单业务applicationQuery:{}", applicationQuery);
        List<ApplicationVO> list = applicationMapper.select(applicationQuery);
        for (int i = 0; i < list.size(); i++) {
            ApplicationVO applicationVO = list.get(i);
            assignAuditUserList(applicationVO);
        }
        return list;
    }


    /*本方法用于给当前传入的申请单VO的审批人数据赋值auditUserIdList与auditUsernameList*/
    private void assignAuditUserList(ApplicationVO applicationVO) {
        //1.准备空集合，存放审批人id与审批人姓名
        List<Long> auditUserIdList = new ArrayList<>();
        List<String> auditUsernameList = new ArrayList<>();
        //2.根据传入的申请单Vo对象，根据其申请单id可以查到对应的审批单对象
        AuditQuery audit = new AuditQuery();
        audit.setApplicationId(applicationVO.getId());
        List<AuditVO> auditVOList = auditService.selectAudit(audit);
        for (int i = 0; i < auditVOList.size(); i++) {
            AuditVO auditVO = auditVOList.get(i);
            Long id = auditVO.getAuditUserId();
            auditUserIdList.add(id);
            UserQuery userQuery = new UserQuery();
            userQuery.setId(id);
            List<UserVO> userVOS = userMapper.UserSelect(userQuery);
            auditUsernameList.add(userVOS.get(0).getUsername());
        }
        //6.需要准备一个拼接工具，帮我们将所有审批人姓名连成一个字符串
        StringJoiner stringJoiner = new StringJoiner(",");
        for (String username : auditUsernameList) {
            stringJoiner.add(username);
        }
        //将准备好的审批人id集合赋值给申请单VO参数的审批人id集合属性
        applicationVO.setAuditUserIdList(auditUserIdList);
        //将准备好的审批人姓名集合赋值给申请单VO参数的审批人姓名集合属性
        applicationVO.setAuditUsernameList(stringJoiner.toString());
    }

}
